package com.iot08.api.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iot08.api.config.redis.RedisFilterService;
import com.iot08.api.service.AccountService;
import com.iot08.api.service.DeviceSanWordService;
import com.iot08.api.service.HCYAuthService;
import com.iot08.api.utils.SpringContextUtil;
import com.iot08.api.vo.request.HCYAuthReqVO;
import com.iot08.api.vo.request.SanWordReqVO;
import com.iot08.common.entity.app.Account;
import com.iot08.common.entity.app.DeviceSanWord;
import com.iot08.common.entity.app.HCYAuth;
import com.iot08.common.utils.DateUtil;
import com.iot08.common.utils.RandomUtil;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.Date;

@Slf4j
@RestController
@RequestMapping("getway/dicpen/")
public class HCY_WordController {

    @Resource
    private HCYAuthService hcyAuthService;

    @Resource
    private DeviceSanWordService deviceSanWordService;


    @Resource
    private RedisFilterService redisFilterService;

    private static  String DPUploadFQKey = "DPUploadFQKey:";

    @Resource
    private AccountService accountService;
    /**
     * 查询用户 中国移动云盘 授权信息
     * @author: Weichao
     * @version 1.0
     */
    @GetMapping("hcyAuthorizationInfo")
    public ResponseMap getHCYAuthorizationInfo(@Validated HCYAuthReqVO vo) {

        Account account = accountService.findById(vo.getOpenid());
        if (account == null) {
            return ResponseMap.fail("用户不存在");
        }
        if (account.getPhone() == null) {
            return ResponseMap.fail("用户号码不存在");
        }

        HCYAuth authOB = hcyAuthService.findById(vo.getOpenid());
        if (authOB == null) {
            authOB = new HCYAuth();
            authOB.setId(vo.getOpenid());
            if(vo.getType() == 1){
                authOB.setProject_type(1); //小寻词典笔
            }else{
                authOB.setProject_type(0); // 默认纽曼词典笔
            }
            authOB.setPhone(account.getPhone());
            authOB.setCreatDate(new Date());
            authOB.setUpdateDate(new Date());
            hcyAuthService.save(authOB);
        }else{
            //
            if( vo.getType() != authOB.getProject_type()){
                log.info("openid:{} 类型不对,更新用户的项目类型 旧:{} ==> 新:{}", vo.getOpenid(), authOB.getProject_type(),vo.getType());
                authOB.setProject_type(vo.getType());
                authOB.setUpdateDate(new Date());
                hcyAuthService.save(authOB);
            }
        }
        JSONObject res = new JSONObject();
        //0:未授权,  1:已授权 2:授权检查已过期,需重新授权  3.用户关闭服务的情况
        int status = 0;
        if (authOB.getIsOff() == 1) {
            status = 3;
            res.put("status", status);
            return ResponseMap.success(res);
        }else{
            if(authOB.getAccesstoken() != null){
                status = 1;
                //检查授权是否过期. 去移动接口进行检查 传auhOB 的对象 (查询用户信息)
                Object serviceDiskInfo = hcyAuthService.getServiceDiskInfo(authOB);
                if(!(serviceDiskInfo instanceof JSONObject)){
                    status = 2;
                }else{
                    log.info("检查授权是否过期. 去移动接口进行检查 传auhOB 的对象 (查询用户信息) openid:{} serviceDiskInfo:{}", authOB.getId(), serviceDiskInfo);
                }
            }
        }


        res.put("status", status);

        if (vo.getWillOpen() != null && vo.getWillOpen() == 1 && status != 1) {

            //生成授权页面请求地址
            //拼接中间页
            String redirectUrl = hcyAuthService.HCYAuthBackTemp_H5URL ; //APP/小程序 请求的这里需填我们服务器自有的Html的回调地址 (移动中间页跳转后,APP/小程序需检测)
            String activeProfile = SpringContextUtil.getActiveProfile();
            if("dev".contains(activeProfile)){
                redirectUrl = hcyAuthService.DevHCYAuthBackTemp_H5URL;
            }
            // 请求ID :base64（appid_yyyyMMddHHmmssSSS+3位随机数）生成。登录成功后用于换取开放平台接口调用所需的唯一凭证accesstoken。
            String qId = String.format("%s_%s%s", hcyAuthService.getAppID(authOB), DateUtil.dateToStr(new Date(), "yyyyMMddHHmmssSSS"), RandomUtil.getRandom(100,999));
            String qIdBase64Str = new String(Base64.getEncoder().encode(qId.getBytes()));
            try{
                //APP端 如果使用半屏 可以使用 halfScreen=1&authHeight=50px halfScreen:1 半屏 authHeight:授权页面高度
                String  urlParam = String.format("?pageType=3&appId=%s&appKey=%s&appTitle=%s&deviceId=%s&uuid=%s&mobile=%s&channelId=%s&redirectUrl=%s",
                        hcyAuthService.getAppID(authOB),
                        hcyAuthService.getAppKey(authOB),
                        hcyAuthService.getAppTitle(authOB),
                        vo.getOpenid(),
                        URLEncoder.encode(qIdBase64Str,"UTF-8"), //此参数用户换取token //单独 URL编码一下
                        account.getPhone(),
                        hcyAuthService.HCYChannelId,
                        URLEncoder.encode(redirectUrl,"UTF-8")//单独 URL编码一下
                );

                String middlePageUrl = hcyAuthService.HCYMiddlePageURL + urlParam;
                res.put("authPageUrl", middlePageUrl);
                res.put("authUUID", qIdBase64Str);
                return ResponseMap.success(res);
            }catch (Exception e){
                log.error("可能编码失败 openid:"+vo.getOpenid(), e);
                return ResponseMap.fail("获取授权页有误");
            }
        }

        return ResponseMap.success(res);
    }


    /**
     * 授权成功接口
     * 用户授权成功后需要 APP/小程序 带上UUID
     * @param vo
     * @return
     */
    @PostMapping("hcyAuthSuccess")
    public ResponseMap hcyAuthSuccess(@Validated HCYAuthReqVO vo){
        String authUUID = vo.getAuthUUID();
        HCYAuth authOB = hcyAuthService.findById(vo.getOpenid());
        if (authOB == null) {
            return ResponseMap.fail("未授权成功,无法获取token");
        }
        String accesstokenWithUUID = hcyAuthService.getAccesstokenWithUUID(authOB, authUUID);
        if(accesstokenWithUUID != null){
            log.info("openid:{} 用户请求移动云盘授权成功.", vo.getOpenid());
        }
        return ResponseMap.success();
    }


    /**
     * 上传单词到云生词本接口
     * @param imei
     * @param vo
     * @param bindingResult
     * @return
     */
    @PostMapping("/{imei}/cloud/post")
    public ResponseMap postCloudStrangenessword(@PathVariable("imei") String imei,
                                                SanWordReqVO vo, BindingResult bindingResult) {


        JSONObject res = new JSONObject();
        res.put("wordId", vo.getWordId());

        HCYAuth auth = hcyAuthService.findById(vo.getOpenid());
        if(auth == null || auth.getAccesstoken() == null){
            return ResponseMap.fail("用户未授权移动云盘");
        } else if (auth.getIsOff() == 1) {
            return ResponseMap.fail("已手动关闭移动云盘,打开后再上传");
        }

        DeviceSanWord deviceSanWord = deviceSanWordService.findById(vo.getWordId());
        String value = redisFilterService.get(DPUploadFQKey + vo.getOpenid());
        if(value != null){
            return ResponseMap.fail("上传云词本频繁,请稍后再试");
        }
        JSONArray deviceSanWordList = new JSONArray();
        deviceSanWordList.add(deviceSanWord);
        boolean upRes = deviceSanWordService.postWordToCloud(deviceSanWordList, auth, vo.getOpenid());
        //限制频繁操作 10s
        redisFilterService.setex(DPUploadFQKey + vo.getOpenid(), 10, vo.getOpenid());

        if(upRes){
            //上传成功
            deviceSanWord.setIsUpdateHCY(1);
            deviceSanWord.setUpdateCloudTime(new Date());
            deviceSanWordService.save(deviceSanWord);
            // 成功可以清除频繁的标识
            redisFilterService.del(DPUploadFQKey + vo.getOpenid());
            log.info("生词 上传云盘成功 imei:{} vo:{} res:{}", imei, vo, res);
            return ResponseMap.success(res);
        }else{
            return ResponseMap.fail("上传云词本失败,请稍后重试");
        }


    }


    /**
     * 查询云生词本的上传记录
     * @param imei
     * @param vo
     * @param bindingResult
     * @return
     */
    @PostMapping("/{imei}/cloud/getUploadCloudRecords")
    public ResponseMap getUploadCloudRecords(@PathVariable("imei") String imei,
                                                SanWordReqVO vo, BindingResult bindingResult) {
        String dateStr = vo.getDateStr(); //yyyyMMdd //eg: 20230912
        if(dateStr == null){
            return ResponseMap.fail("miss dateStr");
        }
        JSONArray upWordList = deviceSanWordService.listUploadRecords(imei,vo.getType(), dateStr, vo.getPage(), vo.getNum());
        JSONObject res = new JSONObject();
        res.put("upWordList", upWordList);
        return ResponseMap.success(res);
    }


    /**
     * 查询用户云盘信息
     * @param imei
     * @param vo
     * @param bindingResult
     * @return
     */
    @PostMapping("/{imei}/cloud/getCloudDiskInfo")
    public ResponseMap getCloudDiskInfo(@PathVariable("imei") String imei,
                                             SanWordReqVO vo, BindingResult bindingResult) {
        /*
        phone:
        usedSize: 1023 //  用户网盘已用空间大小，单位MB
        freeDiskSize: 1  //  用户网盘可用空间大小，单位MB
        diskSize: 1024 //用户网盘空间总量，单位MB
        percentage: 99% //百分比
        */
        //getServiceDiskInfo

        HCYAuth hcyAuth = hcyAuthService.findById(vo.getOpenid());
        Object tempRes = hcyAuthService.getServiceDiskInfo(hcyAuth);
        JSONObject resOB = null;
        if(tempRes instanceof JSONObject){
            resOB = (JSONObject)tempRes;
        }else{
            return ResponseMap.fail("获取用户空间信息错误:"+tempRes);
        }

        JSONObject serviceDiskInfo = resOB.getJSONObject("serviceDiskInfo");
        JSONObject res = new JSONObject();
        res.put("phone", hcyAuth.getPhone());
        long usedSize = serviceDiskInfo.getLongValue("usedSize");
        long totalSize = serviceDiskInfo.getLongValue("totalSize");
        res.put("freeDiskSize", totalSize-usedSize);
        res.put("usedSize", usedSize);
        res.put("diskSize", totalSize);
        res.put("percentage",serviceDiskInfo.getString("percentage") );
        return ResponseMap.success(res);
    }


    /**
     * 授权服务开关接口 (用户手动开启/取消授权)
     * @param vo
     * @param bindingResult
     * @return
     */
    @PostMapping("/cloud/exitConfig")
    public ResponseMap exitConfig(SanWordReqVO vo, BindingResult bindingResult) {
        //如果用户关闭, 那么直接取消这个授权, 删除这个记录, 用户要使用需要重新授权
        HCYAuth auth = hcyAuthService.findById(vo.getOpenid());
        if(auth != null){
            if(vo.getSetOff() == 1){
                log.info("用户:{}手动 操作 关闭取消授权服务", vo.getOpenid());
                hcyAuthService.delById(vo.getOpenid());
                return ResponseMap.success();
            }
        }
        return ResponseMap.fail("无授权状态");

    }
}
